package controller

import (
	"errors"
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntity"
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntityManager"
	"gitee.com/fierce_wolf/go-fox-edge-common/commSql"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Method"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Number"
	"gitee.com/fierce_wolf/go-fox-edge-common/edgeEntity"
	"gitee.com/fierce_wolf/go-fox-edge-common/edgeUtil/ExtendConfigUtils"
	"gitee.com/fierce_wolf/go-fox-edge-common/httpserver"
	"go-fox-edge-kernel-manager/utils/PageUtils"
	"strconv"
	"strings"
)

type deviceManageController struct {
}

func (e *deviceManageController) init() {
	httpserver.Server.POST("/device/page", e.selectEntityPage)
	httpserver.Server.GET("/device/entity", e.queryEntity)
	httpserver.Server.POST("/device/entity", e.insertEntity)
	httpserver.Server.PUT("/device/entity", e.updateEntity)
	httpserver.Server.DELETE("/device/entity", e.deleteEntity)

	httpserver.Server.POST("/device/option", e.selectOptionList)
	httpserver.Server.DELETE("/device/entities", e.deleteEntityList)
	httpserver.Server.POST("/device/export", e.downloadEntityList)
}

func (e *deviceManageController) selectEntityPage(context httpserver.Context, body map[string]interface{}) (interface{}, error) {
	id := Map.GetInt64(body, "id", 0)
	deviceName := Map.GetString(body, "deviceName", "")
	deviceType := Map.GetString(body, "deviceType", "")
	manufacturer := Map.GetString(body, "manufacturer", "")
	channelName := Map.GetString(body, "channelName", "")
	channelType := Map.GetString(body, "channelType", "")
	pageNum := Map.GetInt(body, "pageNum", 1)
	pageSize := Map.GetInt(body, "pageSize", 10)

	filter := ""
	if Map.Has(body, "id") {
		filter += " (id = " + strconv.Itoa(Number.MakeInt(id)) + ") AND"
	}
	if deviceName != "" {
		filter += " (device_name like '%" + deviceName + "%') AND"
	}
	if deviceType != "" {
		filter += " (device_type = '" + deviceType + "') AND"
	}
	if manufacturer != "" {
		filter += " (manufacturer = '" + manufacturer + "') AND"
	}
	if channelName != "" {
		filter += " (channel_name = '" + channelName + "') AND"
	}
	if channelType != "" {
		filter += " (channel_type = '" + channelType + "') AND"
	}
	if filter != "" {
		filter = filter[0 : len(filter)-len("AND")]
	}

	return e.selectEntityListPage(filter, "DESC", pageNum, pageSize)
}

func (e *deviceManageController) selectEntityListPage(filter string, order string, pageNum int, pageSize int) (interface{}, error) {
	// 从数据库的deviceObject中查询总数
	selectCount := PageUtils.MakeSelectCountSQL("tb_device", filter)

	total, err := commSql.QueryCount(selectCount)
	if err != nil {
		return nil, err
	}

	// 分页查询数据
	selectPage := PageUtils.MakeSelectSQLPage("tb_device", nil, nil, filter, order, pageNum, pageSize)
	entityList, err := commSql.Client.Query(edgeEntity.Type.DeviceEntity.Type(), selectPage)
	if err != nil {
		return nil, err
	}

	mapList := commEntity.BuildMapList(entityList)

	// 扩展设备的扩展配置信息
	extendConfigEntityList, err := commEntityManager.GetEntityMap(edgeEntity.Type.ExtendConfigEntity.Type())
	if err != nil {
		return nil, err
	}
	ExtendConfigUtils.ExtendMapList(mapList, extendConfigEntityList, edgeEntity.Type.DeviceEntity.Type())

	data := make(map[string]interface{})
	data["list"] = mapList
	data["total"] = total

	return data, nil

}

func (e *deviceManageController) selectOptionList(context httpserver.Context, body map[string]interface{}) (interface{}, error) {
	// 提取业务参数
	deviceType := Map.GetString(body, "deviceType", "")
	manufacturer := Map.GetString(body, "manufacturer", "")
	field := Map.GetString(body, "field", "")

	// 简单校验参数
	if Method.HasEmpty(field) {
		return nil, errors.New("参数不能为空: field")
	}

	sb := ""
	if field == "deviceName" {
		sb += "SELECT DISTINCT t.device_name FROM tb_device t WHERE 1=1 "
		if !Method.HasEmpty(manufacturer) {
			sb += "AND t.manufacturer = '" + manufacturer + "'"
		}
		if !Method.HasEmpty(deviceType) {
			sb += "AND t.device_type = '" + deviceType + "'"
		}
	}

	entityList, err := commSql.Query(edgeEntity.Type.DeviceEntity.Type(), sb)
	if err != nil {
		return nil, err
	}

	resultList := make([]map[string]interface{}, 0)
	for _, v := range entityList {
		deviceEntity := v.(*edgeEntity.DeviceEntity)

		result := make(map[string]interface{})
		result["value"] = deviceEntity.DeviceName
		result["label"] = deviceEntity.DeviceName

		resultList = append(resultList, result)
	}

	return resultList, nil
}

func (e *deviceManageController) queryEntity(context httpserver.Context) (interface{}, error) {
	str := context.Query("id")
	if str == "" {
		return nil, errors.New("输入的id为null")
	}

	id, err := strconv.ParseInt(str, 10, 64)
	if err != nil {
		return nil, err
	}

	exist := commEntityManager.GetEntityById(edgeEntity.Type.DeviceEntity.Type(), id)
	if exist == nil {
		return nil, errors.New("实体不存在")
	}

	return commEntity.BuildMap(exist), nil
}

func (e *deviceManageController) insertEntity(context httpserver.Context, body map[string]interface{}) (interface{}, error) {
	delete(body, "id")
	return e.insertOrUpdate(context, body)
}

func (e *deviceManageController) updateEntity(context httpserver.Context, body map[string]interface{}) (interface{}, error) {
	return e.insertOrUpdate(context, body)
}

func (e *deviceManageController) insertOrUpdate(context httpserver.Context, body map[string]interface{}) (interface{}, error) {
	// 提取业务参数
	deviceName := Map.GetString(body, "deviceName", "")
	deviceType := Map.GetString(body, "deviceType", "")
	manufacturer := Map.GetString(body, "manufacturer", "")
	channelType := Map.GetString(body, "channelType", "")
	channelName := Map.GetString(body, "channelName", "")
	deviceParam := Map.GetMap(body, "deviceParam", nil)
	extendParam := Map.GetMap(body, "extendParam", nil)

	// 简单校验参数
	if Method.HasEmpty(deviceName, deviceType, manufacturer, channelType, channelName) || Method.HasNull(deviceParam, extendParam) {
		return nil, errors.New("deviceName, deviceType, manufacturer, channelType, channelName, deviceParam, extendParam")
	}

	// 构造作为参数的实体
	entity := edgeEntity.Type.DeviceEntity.Instance()
	entity.DeviceName = deviceName
	entity.DeviceType = deviceType
	entity.Manufacturer = manufacturer
	entity.ChannelType = channelType
	entity.ChannelName = channelName
	entity.DeviceParam = deviceParam
	entity.ExtendParam = extendParam

	// 新增/修改实体：参数不包含id为新增，包含为修改
	if !Map.Has(body, "id") {
		exist, err := commEntityManager.GetEntityByServiceKey(entity.Type(), entity.MakeServiceKey())
		if err != nil {
			return nil, err
		}
		if exist != nil {
			return nil, errors.New("实体已存在")
		}

		err = commEntityManager.InsertEntity(entity)
		if err != nil {
			return nil, err
		}

		return nil, nil
	} else {
		id := Map.GetInt64(body, "id", 0)

		exist := commEntityManager.GetEntityById(entity.Type(), id)
		if exist == nil {
			return nil, errors.New("实体不存在")
		}

		// 修改数据
		entity.BaseEntity.Id = id
		entity.GetBaseEntity().CreateTime = exist.GetBaseEntity().CreateTime
		entity.GetBaseEntity().UpdateTime = exist.GetBaseEntity().UpdateTime
		return nil, commEntityManager.UpdateEntity(entity)
	}
}

func (e *deviceManageController) deleteEntity(context httpserver.Context) (interface{}, error) {
	str := context.Query("id")
	if str == "" {
		return nil, errors.New("输入的id为null")
	}

	id, err := strconv.ParseInt(str, 10, 64)
	if err != nil {
		return nil, err
	}

	exist := commEntityManager.GetEntityById(edgeEntity.Type.DeviceEntity.Type(), id)
	if exist == nil {
		return nil, errors.New("实体不存在")
	}

	err = commEntityManager.DeleteEntity(exist)
	if err != nil {
		return nil, err
	}

	return commEntity.BuildMap(exist), nil
}
func (e *deviceManageController) deleteEntityList(context httpserver.Context) (interface{}, error) {
	ids := context.Query("ids")

	idList := strings.Split(ids, ",")
	for _, str := range idList {
		if str == "" {
			continue
		}
		id, err := strconv.ParseInt(str, 10, 64)
		if err != nil {
			return nil, err
		}

		exist := commEntityManager.GetEntityById(edgeEntity.Type.DeviceEntity.Type(), id)
		if exist == nil {
			return nil, errors.New("实体不存在")
		}

		err = commEntityManager.DeleteEntity(exist)
		if err != nil {
			return nil, err
		}
	}

	return nil, nil
}

func (e *deviceManageController) downloadEntityList(context httpserver.Context, body map[string]interface{}) (interface{}, error) {
	return nil, errors.New("Native版本，不再支持该操作")
}
